using System.Collections.Generic;
using System.Threading.Tasks;

namespace Leo.Core.Domain
{
    public delegate Task UpdateTreePathAndOrderIndexHandler<in TKey>(TKey key, string treePath, int orderIndex) where TKey : struct;

    public class TypedTreeNode<TEntity, TKey> where TEntity : ITreeNodeEntity<TKey> where TKey : struct
    {
        public TypedTreeNode(TEntity node, TypedTreeNode<TEntity, TKey> parentnode, string treePath, int orderIndex)
        {
            this.Id = node.Id;
            this.ParentId = node.ParentId;
            this.Code = node.Code;
            this.Name = node.Name;
            this.Description = node.Description;
            this.OrderIndex = orderIndex;
            this.TreePath = treePath;
            this.ParentNode = parentnode;
            this.DataItem = node;
            this.Nodes = new List<TypedTreeNode<TEntity, TKey>>();
        }

        public TKey Id { get; set; }

        public TKey? ParentId { get; set; }

        public TEntity DataItem { get; set; }

        public string Code { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public int OrderIndex { get; set; }

        public string TreePath { get; set; }

        public List<TypedTreeNode<TEntity, TKey>> Nodes { get; set; }

        public TypedTreeNode<TEntity, TKey> ParentNode { get; set; }


        public static List<TypedTreeNode<TEntity, TKey>> ConvertTreeToList(List<TypedTreeNode<TEntity, TKey>> treeTopList)
        {
            var listTree = new List<TypedTreeNode<TEntity, TKey>>();

            for (int i = 0; i < treeTopList.Count; i++)
            {
                ReadNodesToList(listTree, treeTopList[i]);
            }

            return listTree;
        }

        private static void ReadNodesToList(List<TypedTreeNode<TEntity, TKey>> listTree, TypedTreeNode<TEntity, TKey> typedTreeNode)
        {
            listTree.Add(typedTreeNode);

            foreach (var subNode in typedTreeNode.Nodes)
            {
                ReadNodesToList(listTree, subNode);
            }
        }
    }
}
